#ifdef WIN32
#pragma warning(disable:4267 4819 4996)
#endif // WIN32

#include "CgcTcpClient.h"
#include "cgcaddress.h"
#include <boost/format.hpp>

namespace cgc
{
CgcTcpClient::CgcTcpClient(void)
: m_connectReturned(false)
, m_sReceiveData(_T(""))
{
}

CgcTcpClient::~CgcTcpClient(void)
{
	stopClient();
}

int CgcTcpClient::startClient(const tstring & sCgcServerAddr, unsigned int bindPort)
{
	if (m_tcpClient.get() != 0) return 0;

	CCgcAddress cgcAddress = CCgcAddress(sCgcServerAddr, CCgcAddress::ST_TCP);
	tstring sIp = cgcAddress.getip();
	unsigned short nPort = (unsigned short)cgcAddress.getport();

	if (m_ipService.get() == 0)
		m_ipService = IoService::create();

	TcpClient_Handler::pointer clientHandler = boost::enable_shared_from_this<CgcTcpClient>::shared_from_this();
	//CgcTcpClient::pointer clientHandler = boost::static_pointer_cast<CgcTcpClient, CgcBaseClient>(boost::enable_shared_from_this<CgcBaseClient>::shared_from_this());

	m_tcpClient = TcpClient::create(clientHandler);

	m_connectReturned = false;
	// ?? bindPort
	tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string(sIp.c_str()), nPort);
	m_tcpClient->connect(m_ipService->ioservice(), endpoint);
	m_ipService->start();
	while (!m_connectReturned)
#ifdef WIN32
		Sleep(100);
#else
		usleep(100000);
#endif
	return 0;
}

void CgcTcpClient::stopClient(void)
{
	if (m_tcpClient.get() != 0)
	{
		//m_tcpClient->resetHandler();
		m_tcpClient->disconnect();
	}
	if (m_ipService.get() != 0)
	{
		m_ipService->stop();
	}
	m_tcpClient.reset();
	m_ipService.reset();
}

size_t CgcTcpClient::sendData(const unsigned char * data, size_t size)
{
	BOOST_ASSERT(m_tcpClient.get() != 0);

	if (data == 0 || isInvalidate()) return 0;

	return m_tcpClient->write(data, size);
}

bool CgcTcpClient::isInvalidate(void) const
{
	return m_tcpClient.get() == 0 || !m_tcpClient->is_open();
}

void CgcTcpClient::OnConnected(TcpClientPointer tcpClient)
{
	//BOOST_ASSERT (tcpClient.get() != 0);

	m_connectReturned = true;
	//if (tcpClient->is_open())
	//{
	//	tcp::endpoint local_endpoint = tcpClient->socket()->local_endpoint();
	//	tcp::endpoint remote_endpoint = tcpClient->socket()->remote_endpoint();
	//	m_ipLocal = CCgcAddress(local_endpoint.address().to_string(), local_endpoint.port(), CCgcAddress::ST_TCP);
	//	m_ipRemote = CCgcAddress(remote_endpoint.address().to_string(), remote_endpoint.port(), CCgcAddress::ST_TCP);
	//}
}

void CgcTcpClient::OnReceiveData(TcpClientPointer tcpClient, ReceiveBuffer::pointer data)
{
	BOOST_ASSERT (tcpClient.get() != 0);
	BOOST_ASSERT (data.get() != 0);

	if (data->size() <= 0) return;
	//m_tSendRecv = time(0);
	//this->parseData(CCgcData::create(data->data(), data->size()));
	m_sReceiveData.append(tstring((const char*)data->data(), data->size()));
}

} // namespace cgc
